import Store from 'common/Store'
import Login from 'common/Login'
import Http from 'common/Http'
import DOM from './DOM'
var Translation = require('./Translation')

/** import area */

import Event1 from 'common/Events/Event1';
import Event2 from 'common/Events/Event2';
import Event3 from 'common/Events/Event3';
import Record from './Record';

Object.defineProperty(Array.prototype, LAST, {
  get: function () {
    return this.length ? this[this.length - 1] : -1
  }
})

/** import area */

export namespace _test {
  export class Main implements MainImplements {
    static _ins: Main
    static get instance() {
      return Main._ins || new Main
    }
    constructor() {
      Main._ins = this
    }

    initStoreMap(initMap: StoreInitMap) {
      Store.initMap = initMap
    }

    /** code area */

    init() {

      this.bindEvents()
      this.setZones()
      this.handlerLogin()
      this.handlerRole()

      var promise = Login.instance.checkFbLogin()
      promise && promise.then(data => {
        this.dataHandler(data, () => {
          this.loginSucc(data)
        }, () => {
          location.href = location.origin + location.pathname
          return 'stop'
        })
      })
    }

    activePokeItem = []
    activePokeItemMap = {}
    event1CanClick = true
    event2CanClick = true
    event3CanClick = true

    zoneList: any
    zoneMap: object = {}
    /**
    * 初始化区服信息
    */
    setZones() {
      Http.instance.getZones().then(data => {
        this.dataHandler(data, () => {
          this.zoneList = data.state
          var str = `<option value="0">${Translation.serverSelect}</option>`
          this.zoneList.forEach((item, i) => {
            var { localName, mainGameZoneId } = item
            this.zoneMap[mainGameZoneId] = i
            str += `<option value="${mainGameZoneId}">${localName}</option>`
          })
          DOM.$server.html(str)
        })
      })
    }

    dataHandler(data: EventData, succFn?: Function, failFn?: Function) {
      var { code, state } = data

      if (!code) {
        Store.instance.clear()
        location.reload()
        return
      }

      if (code === 200) {
        succFn && succFn()
      }
      else if (code === 300) { // not login
        Store.instance.clear()
        DOM.popServerConfirm.data('role', false)
        DOM.$role.html('')
        window.server.value = '0'
        Login.instance._isLogin = Login.instance._isRole = false
        this.loginCheck()
      }
      else {
        var flag: any = true
        failFn && (flag = failFn())
        if (flag !== 'stop') {
          var statement
          statement = Translation.codes[code] || (state)
          this.showErr(statement)
        }
      }
    }

    showErr(message: string, config?: any) {
      if (config && config.align) {
        DOM.ctnBox.css({ 'text-align': config.align })
      } else {
        DOM.ctnBox.css({ 'text-align': 'center' })
      }
      DOM.ctnBox.html(message)
      this.showQueue(DOM.popCtn, message)
    }

    consoleLog(cs, tag?) {
      tag ? console.log(tag, cs) : console.log(cs)
    }

    userInfoRender() {
      Login.instance._isLogin = true
      DOM.connect.addClass(HIDE)
      DOM.logged.removeClass(HIDE)
      DOM.logged.find('.username span').html(Store.instance.map.userInfo.userName)
    }

    roleInfoRender() {
      Login.instance._isRole = true
      DOM.logged.find('.zonename, .rolename').removeClass(HIDE)
      DOM.logged.find('.zonename span').html(Store.instance.map.zoneInfo.localName)
      DOM.logged.find('.rolename span').html(Store.instance.map.roleInfo.playerName)

      { // event1
        $.when(
          Event1.instance.queryEvent(INFO).done(data => {
            this.dataHandler(
              data,
              this.consoleLog.bind(this, data.state, 'Event1 INFO'),
              this.consoleLog.bind(this, data.state, 'Event1 INFO')
            )
          }).fail(err => {
            console.error(err)
          }),
          Event1.instance.queryEvent(CDKEYS).then(data => {
            this.dataHandler(
              data,
              this.consoleLog.bind(this, data.state, 'Event1 CDKEYS'),
              this.consoleLog.bind(this, data.state, 'Event1 CDKEYS')
            )
          }).fail(err => {
            console.error(err)
          })
        ).always(data => {
          if (Event1.instance.history.length) {
            DOM.event1Btn.data('state', 'over')
            DOM.event1Btn.attr('class', 'btn gold')
            DOM.event1Btn.text(Translation.achieved)
          } else {
            DOM.event1Btn.data('state', 'reward')
            DOM.event1Btn.attr('class', 'btn gold')
            DOM.event1Btn.text(Translation.get)
          }
        })
      }

      { // event2
        $.when(
          Event2.instance.queryEvent(INFO).done(data => {
            this.dataHandler(
              data,
              this.consoleLog.bind(this, data.state, 'Event2 INFO'),
              this.consoleLog.bind(this, data.state, 'Event2 INFO')
            )
          }).fail(err => {
            console.error(err)
          }),
          Event2.instance.queryEvent(CDKEYS).then(data => {
            this.dataHandler(
              data,
              this.consoleLog.bind(this, data.state, 'Event2 CDKEYS'),
              this.consoleLog.bind(this, data.state, 'Event2 CDKEYS')
            )
          }).fail(err => {
            console.error(err)
          })
        ).always(data => {
          this.event2Render(Event2.instance.info.issue)
        })
      }

      { // event3
        $.when(
          Event3.instance.queryEvent(INFO).done(data => {
            this.dataHandler(
              data,
              this.consoleLog.bind(this, data.state, 'Event3 INFO'),
              this.consoleLog.bind(this, data.state, 'Event3 INFO')
            )
          }).fail(err => {
            console.error(err)
          }),
          Event3.instance.queryEvent(CDKEYS).then(data => {
            this.dataHandler(
              data,
              this.consoleLog.bind(this, data.state, 'Event3 CDKEYS'),
              this.consoleLog.bind(this, data.state, 'Event3 CDKEYS')
            )
          }).fail(err => {
            console.error(err)
          })
        ).always(data => {
          if (Event3.instance.info.gameLogin.length) { // 可以领奖
            if (Event3.instance.history.length) {
              var rws = {}

              Event3.instance.history.forEach((item, i) => {
                rws[item.rewardId] = true
              })

              Event3.instance.info.gameLogin.forEach((item, i) => {
                var btn = DOM.event3CardBtns.eq(i)
                if (!rws.hasOwnProperty(Event3.instance.rewardId[i])) {
                  btn.attr('class', 'btn gold')
                  btn.data('state', 'get')
                  btn.text(Translation.get)
                } else {
                  btn.attr('class', 'btn gold')
                  btn.data('state', 'over')
                  btn.text(Translation.achieved)
                }
              })
            } else {
              Event3.instance.info.gameLogin.forEach((item, i) => {
                var btn = DOM.event3CardBtns.eq(i)
                btn.attr('class', 'btn gold')
                btn.data('state', 'get')
                btn.text(Translation.get)
              })
            }


          }
        })
      }


    }

    handlerLogin(flag?) {
      if (flag) {
        this.userInfoRender()
      } else {
        if (Login.instance.isLogin()) {
          this.userInfoRender()
        } else {
          DOM.connect.removeClass(HIDE)
        }
      }
    }

    handlerRole(flag?) {
      if (flag) {
        this.roleInfoRender()
      } else {
        if (Login.instance.isRole()) {
          this.roleInfoRender()
        }
      }
    }

    queue = []
    showQueue(dom, message?) {

      if (message) {
        dom.message.push(message)
      }

      this.queue.push(dom)
      var length = this.queue.length
      var lastDom = this.queue[length - 2]
      if (length === 1) {
        DOM.mask.removeClass(HIDE)
      } else {
        lastDom.addClass('sink')
      }

      dom.hasClass(HIDE) && dom.removeClass(HIDE)
      dom.hasClass('sink') && dom.removeClass('sink')
    }

    removeQueue() {
      if (this.queue.length) {
        var hide = this.queue.pop()
        var second = this.queue[0]
        var length = this.queue.length

        if (hide.hasClass('ctn')) {
          hide.message.pop()
        }

        if (second && second.hasClass('ctn')) {
          DOM.ctnBox.html(second.message.last)
        } else {
          hide.addClass('hide')
          if (!length) {
            DOM.mask.addClass(HIDE)
          } else {
            var dom = this.queue[length - 1]
            dom.hasClass('sink') && dom.removeClass('sink')
          }
        }


      }
    }

    canChage = true
    zoneId = null
    roleList: RoleInfo[][] = []

    serverChange() {

      if (this.roleList[window.server.value]) {
        DOM.$role.html(this.roleList[window.server.value][0].playerName)
        DOM.popServerConfirm.data('role', true)
        return
      }

      if (this.canChage) {
        this.canChage = false
        this.zoneId = window.server.value
        DOM.$role.html(Translation.querying)
        DOM.popServerConfirm.data('role', false)

        Http.instance.getRole({
          appId: Store.instance.map.activityID,
          gameZoneId: this.zoneId,
          token: Store.instance.map.userInfo.token
        }).then(data => {
          // dom
          DOM.$role.html('')
          this.canChage = true

          if (data.state.length) {
            this.roleList[this.zoneId] = data.state
          }

          if (!this.roleList[this.zoneId]) {
            DOM.$role.html(Translation.noRole)
            DOM.popServerConfirm.data('role', false)
            return
          }

          this.dataHandler(data, () => {
            if (this.zoneId === window.server.value) {
              DOM.$role.html(this.roleList[this.zoneId][0].playerName)
              DOM.popServerConfirm.data('role', true)
            }
          })
          if (this.zoneId !== window.server.value) {
            this.serverChange()
          }
        }).fail(err => {
          this.showErr(Translation.unknown)
          this.canChage = true
          if (this.zoneId !== window.server.value) {
            this.serverChange()
          }
        })
      }
    }


    bindEvents() {

      DOM.loading.addClass('loader')

      DOM.logo.click(() => {
        window.open('https://www.facebook.com/TrainerBattle/')
      })

      DOM.connect.click(() => {
        this.showQueue(DOM.popLogin)
      })

      DOM.mask.click(() => {
        this.removeQueue()
      })

      DOM.x.click(() => {
        this.removeQueue()
      })

      DOM.popServerConfirm.click(() => {
        if (!DOM.popServerConfirm.data('role')) return
        console.log(Store.instance)
        Store.instance.setItem('roleInfo', this.roleList[window.server.value][0])
        console.log(1)
        Store.instance.setItem('zoneInfo', this.zoneList[this.zoneMap[window.server.value]])
        console.log(2)
        this.removeQueue()
        console.log(3)
        this.handlerRole(true)
        console.log(4)
      })

      DOM.logout.click(function () {
        Store.instance.clear()
        location.reload()
      })

      DOM.$server.change(() => {
        this.serverChange()
      })

      DOM.loginBtn.on('click', '.btn', (e) => {
        var target = $(e.target)
        var isFb = target.hasClass('fb')
        if (isFb) {
          Login.instance.fbLogin()
        } else {
          Login.instance.pfLogin().then(data => {
            this.dataHandler(data, () => {
              this.loginSucc(data)
            })
          })
        }
      })

      DOM.event1Btn.click(() => {
        if (!this.loginCheck()) return
        var state = DOM.event1Btn.data('state')
        if (this.event1CanClick && state) {
          var info = Event1.instance.info
          if (info && info.joinTime.sumTime !== 0) {
            this.event1CanClick = false
            Event1.instance.queryEvent(JOIN).then(data => {
              this.dataHandler(data, () => {
                Event1.instance.info = {
                  joinTime: {
                    sumTime: 0
                  }
                }

                Event1.instance.history = [{
                  cdKeys: data.state.cdKeys
                }]

                DOM.event1Btn.data('state', 'over')
                DOM.event1Btn.attr('class', 'btn gold')
                DOM.event1Btn.text(Translation.achieved)

                this.showErr(data.state.cdKeys)

                Record.instance.point1()
              }, () => {
                this.showErr(Translation.event1_not_achieve)
                return 'stop'
              })
              this.event1CanClick = true
            }).fail(err => {
              this.event1CanClick = true
              this.showErr(Translation.noRole)
            })
          } else {
            var history = Event1.instance.history.last
            this.showErr(history.cdKeys)
          }
        }

      })

      DOM.event3Card.on('click', '.btn', (e) => {
        if (!this.loginCheck()) return
        var item = $(e.target)
        var state = item.data('state')
        if (state) {


          switch (state) {
            case 'get':
              var info = new Date(Event3.instance.info.gameLogin.last.countDate).getTime()
              var last = new Date(Store.instance.map.roleInfo.lastLoginDate).getTime()

              if (last < info) {
                this.showErr(Translation.codes[1001])
                return
              }
              var step = Number(e.target.dataset.index)
              if (this.event3CanClick) {
                this.event3CanClick = false
                Event3.instance.queryEvent(JOIN, { step }).then(data => {
                  this.dataHandler(data, () => {
                    this.showErr(Translation.emailOk)
                    var btn = DOM.event3CardBtns.eq(step)
                    btn.data('state', 'over')
                    btn.text(Translation.achieved)

                    if (step === 0) Record.instance.point2()
                  })
                }).done(() => {
                  this.event3CanClick = true
                }).fail((err) => {
                  this.event3CanClick = true
                  console.error(err)
                  this.showErr(Translation.unknown)
                })
              }
              break;
            case 'over':
              this.showErr(Translation.emailOk)
          }

        } else {
          this.showErr(Translation.unfulfill)
        }
      })

      DOM.event2TimebarItems.click((e) => {
        if (!this.loginCheck()) return
        var item = $(e.target)
        if (!item.hasClass('item')) item = $(e.target).parents('.item')
        var index = item.index()
        if (index > Event2.instance.issue) {
          this.showErr(Translation.notStart)
        } else {
          this.event2Render(index)
        }
      })

      DOM.event2PokemonsItemsGL.click((e) => {
        if (!this.loginCheck()) return
        e.stopPropagation()
        if (!Event2.instance.systemTicket[this.timebarIndex] && this.timebarIndex === Event2.instance.issue) {
          var userInfo = Event2.instance.userTicket[this.timebarIndex]
          if (!userInfo) {
            var item = $(e.target)
            var index
            var isL = item.hasClass('poke-l')
            var light, gray
            if (isL) {
              light = item
              gray = item.siblings('.poke-g')
              index = DOM.event2PokemonsItemsL.index(item)
            } else {
              gray = item
              light = item.siblings('.poke-l')
              index = DOM.event2PokemonsItemsG.index(item)
            }
            var prop: string = index + ''
            var i
            if (this.activePokeItemMap.hasOwnProperty(prop)) {
              i = this.activePokeItem.indexOf(index)
              this.activePokeItem.splice(i, 1)
              var { gray, index, light } = this.activePokeItemMap[prop]
              this.pokeItemRender(light, gray)
              delete this.activePokeItemMap[prop]
            } else {
              this.pokeItemRender(gray, light)
              this.activePokeItemMap[prop] = { gray, index, light }
              i = this.activePokeItem.indexOf(index)
              if (i === -1) {
                this.activePokeItem.push(index)
              }
              if (this.activePokeItem.length > 5) {
                prop = this.activePokeItem.shift() + ''
                var { gray, index, light } = this.activePokeItemMap[prop]
                this.pokeItemRender(light, gray)
                delete this.activePokeItemMap[prop]
              }
            }
          }
        }
      })

      DOM.event2Submit.click((e) => {
        if (!this.loginCheck()) return
        var state = DOM.event2Submit.data('state')
        console.log('shindousaigo', state)
        if (state) {
          switch (state) {
            case 'reward':
              this.getGuessReward()
              break;
            case 'join':
              this.joinGuessAct()
              break;
          }
        }
      })

      DOM.event2Overview.click((e) => {
        this.showQueue(DOM.popOverview)
      })

      DOM.event2Record.click((e) => {
        if (!this.loginCheck()) return
        var str = ''
        for (var issue in Event2.instance.gotRewardMap) {
          var isGet = Event2.instance.gotRewardMap[issue]
          str += Translation.issues[<any>issue * 1]
          str += isGet ? Translation.congratulations : Translation.pity
          str += '<br>'
        }
        this.showErr(str, { align: 'left' })
      })

    }

    loginSucc(data) {
      this.removeQueue()
      this.showQueue(DOM.popServer)
      var activetime = new Date().getTime()
      var userInfo = Object.assign({ activetime }, data.state)
      Store.instance.setItem('userInfo', userInfo)
      this.handlerLogin(true)
    }

    pokeItemRender(hide: JQuery<HTMLElement>, show: JQuery<HTMLElement>) {
      hide.addClass(HIDE)
      show.removeClass(HIDE)
    }

    loginCheck() {
      if (!Login.instance._isLogin) {
        this.showQueue(DOM.popLogin)
        return false;
      }
      if (!Login.instance._isRole) {
        this.showQueue(DOM.popServer)
        return false;

      }
      return true
    }


    // event2
    timebarIndex: number
    event2Render(index) {
      this.timebarIndex = index
      this.timebarRender()
      this.crownRender()
      this.userChooseRender()
      this.event2SubmitRender()
    }

    event2SubmitRender() {
      var systemInfo = Event2.instance.systemTicket[this.timebarIndex]
      var userInfo = Event2.instance.userTicket[this.timebarIndex]
      var isGotReward = Event2.instance.gotRewardMap[this.timebarIndex]
      var submit = DOM.event2Submit
      if (systemInfo && systemInfo.length) {
        if (userInfo && userInfo.length) {
          var count = 0
          systemInfo.forEach(number => {
            if (userInfo.indexOf(number) !== -1) count++
          })
          if (count >= 3 && !isGotReward) {
            submit.attr('class', 'btn gold')
            submit.data('state', 'reward')
            submit.data('reward', count - 3)
            submit.html(Translation.reward)
            return
          }
        }
        submit.attr('class', 'btn ed')
        submit.data('state', 'over')
        submit.html(Translation.over)
      } else {
        if (userInfo) {
          submit.attr('class', 'btn gold')
          submit.data('state', 'reward')
          submit.html(Translation.reward)
          return
        }
        submit.attr('class', 'btn gold')
        submit.data('state', 'join')
        submit.html(Translation.join)

      }
    }

    getGuessReward() {

      if (this.event2CanClick) {
        this.event2CanClick = false
        var step = this.timebarIndex
        var submit = DOM.event2Submit

        var rewardId = Event2.instance.rewardId[
          submit.data('reward')
        ]

        var systemInfo = Event2.instance.systemTicket[step]
        console.log('shindousaigo', systemInfo)
        if (systemInfo && systemInfo.length) {
          Event2.instance.queryEvent(JOIN, { step, rewardId }).then(data => {
            this.dataHandler(data, () => {
              this.showErr(Translation.emailOk)
              submit.attr('class', 'btn ed')
              submit.data('state', 'over')
              Event2.instance.gotRewardMap[step] = true
              submit.html(Translation.over)
            })
          }).done(() => {
            this.event2CanClick = true
          }).fail((err) => {
            console.log(err)
            this.showErr(Translation.unknown)
            this.event2CanClick = true
          })
        } else {
          console.log('shindousaigo', Translation.wait)
          this.showErr(Translation.wait)
          this.event2CanClick = true
        }


      }

    }

    joinGuessAct() {
      var length = this.activePokeItem.length
      if (length < 5) {
        this.showErr(Translation.noFive)
        return
      }
      if (this.event2CanClick) {
        this.event2CanClick = false
        var submit = DOM.event2Submit
        var ticket = this.activePokeItem.sort().join('')
        var step = this.timebarIndex
        Event2.instance.queryEvent(JOIN, { ticket, step }).then(data => {
          this.dataHandler(data, () => {
            this.showErr(Translation.joinSucc)
            submit.attr('class', 'btn gold')
            submit.data('state', 'reward')
            submit.html(Translation.reward)
          }, () => {
            if (data.code === 1005) {
              this.showErr(Translation.wait)
              return 'stop'
            }
          })
        }).done(() => {
          this.event2CanClick = true
        }).fail((err) => {
          console.log(err)
          this.showErr(Translation.unknown)
          this.event2CanClick = true
        })
      }

    }

    timebarRender() {
      DOM.event2TimebarItems.eq(this.timebarIndex).removeClass(GRAY).siblings().addClass(GRAY)
    }

    crownRender() {
      var systemInfo = Event2.instance.systemTicket[this.timebarIndex]
      DOM.event2PokemonsItemsC.addClass(HIDE)
      if (systemInfo) {
        systemInfo.forEach(index => {
          DOM.event2PokemonsItemsC.eq(index).removeClass(HIDE)
        })
      }
    }

    userChooseRender() {
      var userInfo = Event2.instance.userTicket[this.timebarIndex]
      if (userInfo) {
        this.pokeItemRender(DOM.event2PokemonsItemsL, DOM.event2PokemonsItemsG)
        userInfo.forEach(index => {
          this.pokeItemRender(DOM.event2PokemonsItemsG.eq(index), DOM.event2PokemonsItemsL.eq(index))
        })
      } else {
        this.pokeItemRender(DOM.event2PokemonsItemsL, DOM.event2PokemonsItemsG)
        if (this.activePokeItem.length && this.timebarIndex === Event2.instance.issue) {
          this.activePokeItem.forEach(index => {
            this.pokeItemRender(DOM.event2PokemonsItemsG.eq(index), DOM.event2PokemonsItemsL.eq(index))
          })
        }
      }
    }

    /** code area */

  }
}
